﻿using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Net;
using HslCommunication.Reflection;

namespace HslCommunication.Profinet.Melsec
{
	/// <summary>
	/// 三菱串口协议的网络版
	/// </summary>
	/// <remarks>
	/// 字读写地址支持的列表如下：
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址范围</term>
	///     <term>地址进制</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>数据寄存器</term>
	///     <term>D</term>
	///     <term>D100,D200</term>
	///     <term>D0-D511,D8000-D8255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>定时器的值</term>
	///     <term>TN</term>
	///     <term>TN10,TN20</term>
	///     <term>TN0-TN255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>计数器的值</term>
	///     <term>CN</term>
	///     <term>CN10,CN20</term>
	///     <term>CN0-CN199,CN200-CN255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	/// </list>
	/// 位地址支持的列表如下：
	/// <list type="table">
	///   <listheader>
	///     <term>地址名称</term>
	///     <term>地址代号</term>
	///     <term>示例</term>
	///     <term>地址范围</term>
	///     <term>地址进制</term>
	///     <term>备注</term>
	///   </listheader>
	///   <item>
	///     <term>内部继电器</term>
	///     <term>M</term>
	///     <term>M100,M200</term>
	///     <term>M0-M1023,M8000-M8255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>输入继电器</term>
	///     <term>X</term>
	///     <term>X1,X20</term>
	///     <term>X0-X177</term>
	///     <term>8</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>输出继电器</term>
	///     <term>Y</term>
	///     <term>Y10,Y20</term>
	///     <term>Y0-Y177</term>
	///     <term>8</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>步进继电器</term>
	///     <term>S</term>
	///     <term>S100,S200</term>
	///     <term>S0-S999</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>定时器触点</term>
	///     <term>TS</term>
	///     <term>TS10,TS20</term>
	///     <term>TS0-TS255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>定时器线圈</term>
	///     <term>TC</term>
	///     <term>TC10,TC20</term>
	///     <term>TC0-TC255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>计数器触点</term>
	///     <term>CS</term>
	///     <term>CS10,CS20</term>
	///     <term>CS0-CS255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	///   <item>
	///     <term>计数器线圈</term>
	///     <term>CC</term>
	///     <term>CC10,CC20</term>
	///     <term>CC0-CC255</term>
	///     <term>10</term>
	///     <term></term>
	///   </item>
	/// </list>
	/// </remarks>
	/// <example>
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="Usage" title="简单的使用" />
	/// </example>
	// Token: 0x0200006B RID: 107
	public class MelsecFxSerialOverTcp : NetworkDeviceBase
	{
		/// <summary>
		/// 实例化网络版的三菱的串口协议的通讯对象<br />
		/// Instantiate the communication object of Mitsubishi's serial protocol on the network
		/// </summary>
		// Token: 0x060008A9 RID: 2217 RVA: 0x0002FB3E File Offset: 0x0002DD3E
		public MelsecFxSerialOverTcp()
		{
			base.WordLength = 1;
			base.ByteTransform = new RegularByteTransform();
			this.IsNewVersion = true;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <summary>
		/// 指定ip地址及端口号来实例化三菱的串口协议的通讯对象<br />
		/// Specify the IP address and port number to instantiate the communication object of Mitsubishi's serial protocol
		/// </summary>
		/// <param name="ipAddress">Ip地址</param>
		/// <param name="port">端口号</param>
		// Token: 0x060008AA RID: 2218 RVA: 0x0002FB74 File Offset: 0x0002DD74
		public MelsecFxSerialOverTcp(string ipAddress, int port)
		{
			base.WordLength = 1;
			this.IpAddress = ipAddress;
			this.Port = port;
			base.ByteTransform = new RegularByteTransform();
			this.IsNewVersion = true;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <summary>
		/// 当前的编程口协议是否为新版，默认为新版，如果无法读取，切换旧版再次尝试<br />
		/// Whether the current programming port protocol is the new version, the default is the new version, 
		/// if it cannot be read, switch to the old version and try again
		/// </summary>
		// Token: 0x17000186 RID: 390
		// (get) Token: 0x060008AB RID: 2219 RVA: 0x0002FBC2 File Offset: 0x0002DDC2
		// (set) Token: 0x060008AC RID: 2220 RVA: 0x0002FBCA File Offset: 0x0002DDCA
		public bool IsNewVersion { get; set; }

		/// <inheritdoc />
		/// <example>
		/// 假设起始地址为D100，D100存储了温度，100.6℃值为1006，D101存储了压力，1.23Mpa值为123，D102，D103存储了产量计数，读取如下：
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadExample2" title="Read示例" />
		/// 以下是读取不同类型数据的示例
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadExample1" title="Read示例" />
		/// </example>
		// Token: 0x060008AD RID: 2221 RVA: 0x0002FBD3 File Offset: 0x0002DDD3
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			return MelsecFxSerialOverTcp.ReadHelper(address, length, new Func<byte[], OperateResult<byte[]>>(base.ReadFromCoreServer), this.IsNewVersion);
		}

		/// <inheritdoc />
		/// <example>
		/// 假设起始地址为D100，D100存储了温度，100.6℃值为1006，D101存储了压力，1.23Mpa值为123，D102，D103存储了产量计数，写入如下：
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="WriteExample2" title="Write示例" />
		/// 以下是读取不同类型数据的示例
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="WriteExample1" title="Write示例" />
		/// </example>
		// Token: 0x060008AE RID: 2222 RVA: 0x0002FBEE File Offset: 0x0002DDEE
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			return MelsecFxSerialOverTcp.WriteHelper(address, value, new Func<byte[], OperateResult<byte[]>>(base.ReadFromCoreServer), this.IsNewVersion);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecFxSerialOverTcp.Read(System.String,System.UInt16)" />
		// Token: 0x060008AF RID: 2223 RVA: 0x0002FC0C File Offset: 0x0002DE0C
		[DebuggerStepThrough]
		public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			MelsecFxSerialOverTcp.<ReadAsync>d__8 <ReadAsync>d__ = new MelsecFxSerialOverTcp.<ReadAsync>d__8();
			<ReadAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
			<ReadAsync>d__.<>4__this = this;
			<ReadAsync>d__.address = address;
			<ReadAsync>d__.length = length;
			<ReadAsync>d__.<>1__state = -1;
			<ReadAsync>d__.<>t__builder.Start<MelsecFxSerialOverTcp.<ReadAsync>d__8>(ref <ReadAsync>d__);
			return <ReadAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecFxSerialOverTcp.Write(System.String,System.Byte[])" />
		// Token: 0x060008B0 RID: 2224 RVA: 0x0002FC60 File Offset: 0x0002DE60
		[DebuggerStepThrough]
		public override Task<OperateResult> WriteAsync(string address, byte[] value)
		{
			MelsecFxSerialOverTcp.<WriteAsync>d__9 <WriteAsync>d__ = new MelsecFxSerialOverTcp.<WriteAsync>d__9();
			<WriteAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<WriteAsync>d__.<>4__this = this;
			<WriteAsync>d__.address = address;
			<WriteAsync>d__.value = value;
			<WriteAsync>d__.<>1__state = -1;
			<WriteAsync>d__.<>t__builder.Start<MelsecFxSerialOverTcp.<WriteAsync>d__9>(ref <WriteAsync>d__);
			return <WriteAsync>d__.<>t__builder.Task;
		}

		/// <summary>
		/// 从三菱PLC中批量读取位软元件，返回读取结果，该读取地址最好从0，16，32...等开始读取，这样可以读取比较长得数据数组<br />
		/// Read bit devices from Mitsubishi PLC in batches and return the read result. The read address should preferably be read from 0, 16, 32, etc., so that you can read the longer data array.
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">读取的长度</param>
		/// <returns>带成功标志的结果数据对象</returns>
		/// <example>
		///  <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadBool" title="Bool类型示例" />
		/// </example>
		// Token: 0x060008B1 RID: 2225 RVA: 0x0002FCB2 File Offset: 0x0002DEB2
		[HslMqttApi("ReadBoolArray", "")]
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			return MelsecFxSerialOverTcp.ReadBoolHelper(address, length, new Func<byte[], OperateResult<byte[]>>(base.ReadFromCoreServer));
		}

		/// <inheritdoc />
		// Token: 0x060008B2 RID: 2226 RVA: 0x0002FCC7 File Offset: 0x0002DEC7
		[HslMqttApi("WriteBool", "")]
		public override OperateResult Write(string address, bool value)
		{
			return MelsecFxSerialOverTcp.WriteHelper(address, value, new Func<byte[], OperateResult<byte[]>>(base.ReadFromCoreServer));
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Melsec.MelsecFxSerialOverTcp.ReadBool(System.String,System.UInt16)" />
		// Token: 0x060008B3 RID: 2227 RVA: 0x0002FCDC File Offset: 0x0002DEDC
		[DebuggerStepThrough]
		public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
		{
			MelsecFxSerialOverTcp.<ReadBoolAsync>d__12 <ReadBoolAsync>d__ = new MelsecFxSerialOverTcp.<ReadBoolAsync>d__12();
			<ReadBoolAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
			<ReadBoolAsync>d__.<>4__this = this;
			<ReadBoolAsync>d__.address = address;
			<ReadBoolAsync>d__.length = length;
			<ReadBoolAsync>d__.<>1__state = -1;
			<ReadBoolAsync>d__.<>t__builder.Start<MelsecFxSerialOverTcp.<ReadBoolAsync>d__12>(ref <ReadBoolAsync>d__);
			return <ReadBoolAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc />
		// Token: 0x060008B4 RID: 2228 RVA: 0x0002FD30 File Offset: 0x0002DF30
		[DebuggerStepThrough]
		public override Task<OperateResult> WriteAsync(string address, bool value)
		{
			MelsecFxSerialOverTcp.<WriteAsync>d__13 <WriteAsync>d__ = new MelsecFxSerialOverTcp.<WriteAsync>d__13();
			<WriteAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
			<WriteAsync>d__.<>4__this = this;
			<WriteAsync>d__.address = address;
			<WriteAsync>d__.value = value;
			<WriteAsync>d__.<>1__state = -1;
			<WriteAsync>d__.<>t__builder.Start<MelsecFxSerialOverTcp.<WriteAsync>d__13>(ref <WriteAsync>d__);
			return <WriteAsync>d__.<>t__builder.Task;
		}

		/// <inheritdoc />
		// Token: 0x060008B5 RID: 2229 RVA: 0x0002FD82 File Offset: 0x0002DF82
		public override string ToString()
		{
			return string.Format("MelsecFxSerialOverTcp[{0}:{1}]", this.IpAddress, this.Port);
		}

		/// <summary>
		/// 从三菱PLC中读取想要的数据，返回读取结果
		/// </summary>
		/// <param name="address">读取地址，，支持的类型参考文档说明</param>
		/// <param name="length">读取的数据长度</param>
		/// <param name="readCore">指定的通道信息</param>
		/// <param name="isNewVersion">是否是新版的串口访问类</param>
		/// <returns>带成功标志的结果数据对象</returns>
		/// <example>
		/// 假设起始地址为D100，D100存储了温度，100.6℃值为1006，D101存储了压力，1.23Mpa值为123，D102，D103存储了产量计数，读取如下：
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadExample2" title="Read示例" />
		/// 以下是读取不同类型数据的示例
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadExample1" title="Read示例" />
		/// </example>
		// Token: 0x060008B6 RID: 2230 RVA: 0x0002FDA0 File Offset: 0x0002DFA0
		public static OperateResult<byte[]> ReadHelper(string address, ushort length, Func<byte[], OperateResult<byte[]>> readCore, bool isNewVersion)
		{
			OperateResult<byte[]> operateResult = MelsecFxSerialOverTcp.BuildReadWordCommand(address, length, isNewVersion);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult operateResult3 = MelsecFxSerialOverTcp.CheckPlcReadResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						result = MelsecFxSerialOverTcp.ExtractActualData(operateResult2.Content);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 从三菱PLC中批量读取位软元件，返回读取结果，该读取地址最好从0，16，32...等开始读取，这样可以读取比较长得数据数组
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">读取的长度</param>
		/// <param name="readCore">指定的通道信息</param>
		/// <returns>带成功标志的结果数据对象</returns>
		/// <example>
		///  <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="ReadBool" title="Bool类型示例" />
		/// </example>
		// Token: 0x060008B7 RID: 2231 RVA: 0x0002FE2C File Offset: 0x0002E02C
		public static OperateResult<bool[]> ReadBoolHelper(string address, ushort length, Func<byte[], OperateResult<byte[]>> readCore)
		{
			OperateResult<byte[], int> operateResult = MelsecFxSerialOverTcp.BuildReadBoolCommand(address, length);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				OperateResult<byte[]> operateResult2 = readCore(operateResult.Content1);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<bool[]>(operateResult2);
				}
				else
				{
					OperateResult operateResult3 = MelsecFxSerialOverTcp.CheckPlcReadResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<bool[]>(operateResult3);
					}
					else
					{
						result = MelsecFxSerialOverTcp.ExtractActualBoolData(operateResult2.Content, operateResult.Content2, (int)length);
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 向PLC写入数据，数据格式为原始的字节类型
		/// </summary>
		/// <param name="address">初始地址，支持的类型参考文档说明</param>
		/// <param name="value">原始的字节数据</param>
		/// <param name="readCore">指定的通道信息</param>
		/// <param name="isNewVersion">是否是新版的串口访问类</param>
		/// <example>
		/// 假设起始地址为D100，D100存储了温度，100.6℃值为1006，D101存储了压力，1.23Mpa值为123，D102，D103存储了产量计数，写入如下：
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="WriteExample2" title="Write示例" />
		/// 以下是读取不同类型数据的示例
		/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecFxSerial.cs" region="WriteExample1" title="Write示例" />
		/// </example>
		/// <returns>是否写入成功的结果对象</returns>
		// Token: 0x060008B8 RID: 2232 RVA: 0x0002FEBC File Offset: 0x0002E0BC
		public static OperateResult WriteHelper(string address, byte[] value, Func<byte[], OperateResult<byte[]>> readCore, bool isNewVersion)
		{
			OperateResult<byte[]> operateResult = MelsecFxSerialOverTcp.BuildWriteWordCommand(address, value, isNewVersion);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult operateResult3 = MelsecFxSerialOverTcp.CheckPlcWriteResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 强制写入位数据的通断，支持的类型参考文档说明
		/// </summary>
		/// <param name="address">地址信息</param>
		/// <param name="value">是否为通</param>
		/// <param name="readCore">指定的通道信息</param>
		/// <returns>是否写入成功的结果对象</returns>
		// Token: 0x060008B9 RID: 2233 RVA: 0x0002FF34 File Offset: 0x0002E134
		public static OperateResult WriteHelper(string address, bool value, Func<byte[], OperateResult<byte[]>> readCore)
		{
			OperateResult<byte[]> operateResult = MelsecFxSerialOverTcp.BuildWriteBoolPacket(address, value);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = readCore(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult operateResult3 = MelsecFxSerialOverTcp.CheckPlcWriteResponse(operateResult2.Content);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 检查PLC返回的读取数据是否是正常的
		/// </summary>
		/// <param name="ack">Plc反馈的数据信息</param>
		/// <returns>检查结果</returns>
		// Token: 0x060008BA RID: 2234 RVA: 0x0002FFA8 File Offset: 0x0002E1A8
		public static OperateResult CheckPlcReadResponse(byte[] ack)
		{
			bool flag = ack.Length == 0;
			OperateResult result;
			if (flag)
			{
				result = new OperateResult(StringResources.Language.MelsecFxReceiveZero);
			}
			else
			{
				bool flag2 = ack[0] == 21;
				if (flag2)
				{
					result = new OperateResult(StringResources.Language.MelsecFxAckNagative + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
				}
				else
				{
					bool flag3 = ack[0] != 2;
					if (flag3)
					{
						result = new OperateResult(StringResources.Language.MelsecFxAckWrong + ack[0].ToString() + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
					}
					else
					{
						bool flag4 = !MelsecHelper.CheckCRC(ack);
						if (flag4)
						{
							result = new OperateResult(StringResources.Language.MelsecFxCrcCheckFailed);
						}
						else
						{
							result = OperateResult.CreateSuccessResult();
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 检查PLC返回的写入的数据是否是正常的
		/// </summary>
		/// <param name="ack">Plc反馈的数据信息</param>
		/// <returns>检查结果</returns>
		// Token: 0x060008BB RID: 2235 RVA: 0x0003006C File Offset: 0x0002E26C
		public static OperateResult CheckPlcWriteResponse(byte[] ack)
		{
			bool flag = ack.Length == 0;
			OperateResult result;
			if (flag)
			{
				result = new OperateResult(StringResources.Language.MelsecFxReceiveZero);
			}
			else
			{
				bool flag2 = ack[0] == 21;
				if (flag2)
				{
					result = new OperateResult(StringResources.Language.MelsecFxAckNagative + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
				}
				else
				{
					bool flag3 = ack[0] != 6;
					if (flag3)
					{
						result = new OperateResult(StringResources.Language.MelsecFxAckWrong + ack[0].ToString() + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 生成位写入的数据报文信息，该报文可直接用于发送串口给PLC
		/// </summary>
		/// <param name="address">地址信息，每个地址存在一定的范围，需要谨慎传入数据。举例：M10,S10,X5,Y10,C10,T10</param>
		/// <param name="value"><c>True</c>或是<c>False</c></param>
		/// <returns>带报文信息的结果对象</returns>
		// Token: 0x060008BC RID: 2236 RVA: 0x0003010C File Offset: 0x0002E30C
		public static OperateResult<byte[]> BuildWriteBoolPacket(string address, bool value)
		{
			OperateResult<MelsecMcDataType, ushort> operateResult = MelsecFxSerialOverTcp.FxAnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				ushort num = operateResult.Content2;
				bool flag2 = operateResult.Content1 == MelsecMcDataType.M;
				if (flag2)
				{
					bool flag3 = num >= 8000;
					if (flag3)
					{
						num = num - 8000 + 3840;
					}
					else
					{
						num += 2048;
					}
				}
				else
				{
					bool flag4 = operateResult.Content1 == MelsecMcDataType.S;
					if (flag4)
					{
						num = num;
					}
					else
					{
						bool flag5 = operateResult.Content1 == MelsecMcDataType.X;
						if (flag5)
						{
							num += 1024;
						}
						else
						{
							bool flag6 = operateResult.Content1 == MelsecMcDataType.Y;
							if (flag6)
							{
								num += 1280;
							}
							else
							{
								bool flag7 = operateResult.Content1 == MelsecMcDataType.CS;
								if (flag7)
								{
									num += 448;
								}
								else
								{
									bool flag8 = operateResult.Content1 == MelsecMcDataType.CC;
									if (flag8)
									{
										num += 960;
									}
									else
									{
										bool flag9 = operateResult.Content1 == MelsecMcDataType.CN;
										if (flag9)
										{
											num += 3584;
										}
										else
										{
											bool flag10 = operateResult.Content1 == MelsecMcDataType.TS;
											if (flag10)
											{
												num += 192;
											}
											else
											{
												bool flag11 = operateResult.Content1 == MelsecMcDataType.TC;
												if (flag11)
												{
													num += 704;
												}
												else
												{
													bool flag12 = operateResult.Content1 == MelsecMcDataType.TN;
													if (!flag12)
													{
														return new OperateResult<byte[]>(StringResources.Language.MelsecCurrentTypeNotSupportedBitOperate);
													}
													num += 1536;
												}
											}
										}
									}
								}
							}
						}
					}
				}
				byte[] array = new byte[9];
				array[0] = 2;
				array[1] = (value ? 55 : 56);
				array[2] = SoftBasic.BuildAsciiBytesFrom(num)[2];
				array[3] = SoftBasic.BuildAsciiBytesFrom(num)[3];
				array[4] = SoftBasic.BuildAsciiBytesFrom(num)[0];
				array[5] = SoftBasic.BuildAsciiBytesFrom(num)[1];
				array[6] = 3;
				MelsecHelper.FxCalculateCRC(array).CopyTo(array, 7);
				result = OperateResult.CreateSuccessResult<byte[]>(array);
			}
			return result;
		}

		/// <summary>
		/// 根据类型地址长度确认需要读取的指令头
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">长度</param>
		/// <param name="isNewVersion">是否是新版的串口访问类</param>
		/// <returns>带有成功标志的指令数据</returns>
		// Token: 0x060008BD RID: 2237 RVA: 0x00030314 File Offset: 0x0002E514
		public static OperateResult<byte[]> BuildReadWordCommand(string address, ushort length, bool isNewVersion)
		{
			OperateResult<ushort> operateResult = MelsecFxSerialOverTcp.FxCalculateWordStartAddress(address, isNewVersion);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				length *= 2;
				ushort content = operateResult.Content;
				if (isNewVersion)
				{
					byte[] array = new byte[13];
					array[0] = 2;
					array[1] = 69;
					array[2] = 48;
					array[3] = 48;
					array[4] = SoftBasic.BuildAsciiBytesFrom(content)[0];
					array[5] = SoftBasic.BuildAsciiBytesFrom(content)[1];
					array[6] = SoftBasic.BuildAsciiBytesFrom(content)[2];
					array[7] = SoftBasic.BuildAsciiBytesFrom(content)[3];
					array[8] = SoftBasic.BuildAsciiBytesFrom((byte)length)[0];
					array[9] = SoftBasic.BuildAsciiBytesFrom((byte)length)[1];
					array[10] = 3;
					MelsecHelper.FxCalculateCRC(array).CopyTo(array, 11);
					result = OperateResult.CreateSuccessResult<byte[]>(array);
				}
				else
				{
					byte[] array2 = new byte[11];
					array2[0] = 2;
					array2[1] = 48;
					array2[2] = SoftBasic.BuildAsciiBytesFrom(content)[0];
					array2[3] = SoftBasic.BuildAsciiBytesFrom(content)[1];
					array2[4] = SoftBasic.BuildAsciiBytesFrom(content)[2];
					array2[5] = SoftBasic.BuildAsciiBytesFrom(content)[3];
					array2[6] = SoftBasic.BuildAsciiBytesFrom((byte)length)[0];
					array2[7] = SoftBasic.BuildAsciiBytesFrom((byte)length)[1];
					array2[8] = 3;
					MelsecHelper.FxCalculateCRC(array2).CopyTo(array2, 9);
					result = OperateResult.CreateSuccessResult<byte[]>(array2);
				}
			}
			return result;
		}

		/// <summary>
		/// 根据类型地址长度确认需要读取的指令头
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="length">bool数组长度</param>
		/// <returns>带有成功标志的指令数据</returns>
		// Token: 0x060008BE RID: 2238 RVA: 0x00030468 File Offset: 0x0002E668
		public static OperateResult<byte[], int> BuildReadBoolCommand(string address, ushort length)
		{
			OperateResult<ushort, ushort, ushort> operateResult = MelsecFxSerialOverTcp.FxCalculateBoolStartAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[], int> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[], int>(operateResult);
			}
			else
			{
				ushort num = (operateResult.Content2 + length - 1) / 8 - operateResult.Content2 / 8 + 1;
				ushort content = operateResult.Content1;
				byte[] array = new byte[11];
				array[0] = 2;
				array[1] = 48;
				array[2] = SoftBasic.BuildAsciiBytesFrom(content)[0];
				array[3] = SoftBasic.BuildAsciiBytesFrom(content)[1];
				array[4] = SoftBasic.BuildAsciiBytesFrom(content)[2];
				array[5] = SoftBasic.BuildAsciiBytesFrom(content)[3];
				array[6] = SoftBasic.BuildAsciiBytesFrom((byte)num)[0];
				array[7] = SoftBasic.BuildAsciiBytesFrom((byte)num)[1];
				array[8] = 3;
				MelsecHelper.FxCalculateCRC(array).CopyTo(array, 9);
				result = OperateResult.CreateSuccessResult<byte[], int>(array, (int)operateResult.Content3);
			}
			return result;
		}

		/// <summary>
		/// 根据类型地址以及需要写入的数据来生成指令头
		/// </summary>
		/// <param name="address">起始地址</param>
		/// <param name="value">实际的数据信息</param>
		/// <param name="isNewVersion">是否是新版的串口访问类</param>
		/// <returns>带有成功标志的指令数据</returns>
		// Token: 0x060008BF RID: 2239 RVA: 0x00030534 File Offset: 0x0002E734
		public static OperateResult<byte[]> BuildWriteWordCommand(string address, byte[] value, bool isNewVersion)
		{
			OperateResult<ushort> operateResult = MelsecFxSerialOverTcp.FxCalculateWordStartAddress(address, isNewVersion);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				bool flag2 = value != null;
				if (flag2)
				{
					value = SoftBasic.BuildAsciiBytesFrom(value);
				}
				ushort content = operateResult.Content;
				if (isNewVersion)
				{
					byte[] array = new byte[13 + value.Length];
					array[0] = 2;
					array[1] = 69;
					array[2] = 49;
					array[3] = 48;
					array[4] = SoftBasic.BuildAsciiBytesFrom(content)[0];
					array[5] = SoftBasic.BuildAsciiBytesFrom(content)[1];
					array[6] = SoftBasic.BuildAsciiBytesFrom(content)[2];
					array[7] = SoftBasic.BuildAsciiBytesFrom(content)[3];
					array[8] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[0];
					array[9] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[1];
					Array.Copy(value, 0, array, 10, value.Length);
					array[array.Length - 3] = 3;
					MelsecHelper.FxCalculateCRC(array).CopyTo(array, array.Length - 2);
					result = OperateResult.CreateSuccessResult<byte[]>(array);
				}
				else
				{
					byte[] array2 = new byte[11 + value.Length];
					array2[0] = 2;
					array2[1] = 49;
					array2[2] = SoftBasic.BuildAsciiBytesFrom(content)[0];
					array2[3] = SoftBasic.BuildAsciiBytesFrom(content)[1];
					array2[4] = SoftBasic.BuildAsciiBytesFrom(content)[2];
					array2[5] = SoftBasic.BuildAsciiBytesFrom(content)[3];
					array2[6] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[0];
					array2[7] = SoftBasic.BuildAsciiBytesFrom((byte)(value.Length / 2))[1];
					Array.Copy(value, 0, array2, 8, value.Length);
					array2[array2.Length - 3] = 3;
					MelsecHelper.FxCalculateCRC(array2).CopyTo(array2, array2.Length - 2);
					result = OperateResult.CreateSuccessResult<byte[]>(array2);
				}
			}
			return result;
		}

		/// <summary>
		/// 从PLC反馈的数据进行提炼操作
		/// </summary>
		/// <param name="response">PLC反馈的真实数据</param>
		/// <returns>数据提炼后的真实数据</returns>
		// Token: 0x060008C0 RID: 2240 RVA: 0x000306DC File Offset: 0x0002E8DC
		public static OperateResult<byte[]> ExtractActualData(byte[] response)
		{
			OperateResult<byte[]> result;
			try
			{
				byte[] array = new byte[(response.Length - 4) / 2];
				for (int i = 0; i < array.Length; i++)
				{
					byte[] bytes = new byte[]
					{
						response[i * 2 + 1],
						response[i * 2 + 2]
					};
					array[i] = Convert.ToByte(Encoding.ASCII.GetString(bytes), 16);
				}
				result = OperateResult.CreateSuccessResult<byte[]>(array);
			}
			catch (Exception ex)
			{
				result = new OperateResult<byte[]>
				{
					Message = string.Concat(new string[]
					{
						"Extract Msg：",
						ex.Message,
						Environment.NewLine,
						"Data: ",
						SoftBasic.ByteToHexString(response)
					})
				};
			}
			return result;
		}

		/// <summary>
		/// 从PLC反馈的数据进行提炼bool数组操作
		/// </summary>
		/// <param name="response">PLC反馈的真实数据</param>
		/// <param name="start">起始提取的点信息</param>
		/// <param name="length">bool数组的长度</param>
		/// <returns>数据提炼后的真实数据</returns>
		// Token: 0x060008C1 RID: 2241 RVA: 0x000307A8 File Offset: 0x0002E9A8
		public static OperateResult<bool[]> ExtractActualBoolData(byte[] response, int start, int length)
		{
			OperateResult<byte[]> operateResult = MelsecFxSerialOverTcp.ExtractActualData(response);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				try
				{
					bool[] array = new bool[length];
					bool[] array2 = SoftBasic.ByteToBoolArray(operateResult.Content, operateResult.Content.Length * 8);
					for (int i = 0; i < length; i++)
					{
						array[i] = array2[i + start];
					}
					result = OperateResult.CreateSuccessResult<bool[]>(array);
				}
				catch (Exception ex)
				{
					result = new OperateResult<bool[]>
					{
						Message = string.Concat(new string[]
						{
							"Extract Msg：",
							ex.Message,
							Environment.NewLine,
							"Data: ",
							SoftBasic.ByteToHexString(response)
						})
					};
				}
			}
			return result;
		}

		/// <summary>
		/// 解析数据地址成不同的三菱地址类型
		/// </summary>
		/// <param name="address">数据地址</param>
		/// <returns>地址结果对象</returns>
		// Token: 0x060008C2 RID: 2242 RVA: 0x00030880 File Offset: 0x0002EA80
		private static OperateResult<MelsecMcDataType, ushort> FxAnalysisAddress(string address)
		{
			OperateResult<MelsecMcDataType, ushort> operateResult = new OperateResult<MelsecMcDataType, ushort>();
			try
			{
				char c = address[0];
				char c2 = c;
				if (c2 <= 'Y')
				{
					if (c2 <= 'D')
					{
						if (c2 == 'C')
						{
							goto IL_284;
						}
						if (c2 != 'D')
						{
							goto IL_37A;
						}
						goto IL_12C;
					}
					else if (c2 != 'M')
					{
						switch (c2)
						{
						case 'S':
							goto IL_15B;
						case 'T':
							goto IL_18A;
						case 'U':
						case 'V':
						case 'W':
							goto IL_37A;
						case 'X':
							goto IL_E0;
						case 'Y':
							goto IL_106;
						default:
							goto IL_37A;
						}
					}
				}
				else if (c2 <= 'd')
				{
					if (c2 == 'c')
					{
						goto IL_284;
					}
					if (c2 != 'd')
					{
						goto IL_37A;
					}
					goto IL_12C;
				}
				else if (c2 != 'm')
				{
					switch (c2)
					{
					case 's':
						goto IL_15B;
					case 't':
						goto IL_18A;
					case 'u':
					case 'v':
					case 'w':
						goto IL_37A;
					case 'x':
						goto IL_E0;
					case 'y':
						goto IL_106;
					default:
						goto IL_37A;
					}
				}
				operateResult.Content1 = MelsecMcDataType.M;
				operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.M.FromBase);
				goto IL_38A;
				IL_E0:
				operateResult.Content1 = MelsecMcDataType.X;
				operateResult.Content2 = Convert.ToUInt16(address.Substring(1), 8);
				goto IL_38A;
				IL_106:
				operateResult.Content1 = MelsecMcDataType.Y;
				operateResult.Content2 = Convert.ToUInt16(address.Substring(1), 8);
				goto IL_38A;
				IL_12C:
				operateResult.Content1 = MelsecMcDataType.D;
				operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.D.FromBase);
				goto IL_38A;
				IL_15B:
				operateResult.Content1 = MelsecMcDataType.S;
				operateResult.Content2 = Convert.ToUInt16(address.Substring(1), MelsecMcDataType.S.FromBase);
				goto IL_38A;
				IL_18A:
				bool flag = address[1] == 'N' || address[1] == 'n';
				if (flag)
				{
					operateResult.Content1 = MelsecMcDataType.TN;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TN.FromBase);
					goto IL_38A;
				}
				bool flag2 = address[1] == 'S' || address[1] == 's';
				if (flag2)
				{
					operateResult.Content1 = MelsecMcDataType.TS;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TS.FromBase);
					goto IL_38A;
				}
				bool flag3 = address[1] == 'C' || address[1] == 'c';
				if (flag3)
				{
					operateResult.Content1 = MelsecMcDataType.TC;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.TC.FromBase);
					goto IL_38A;
				}
				throw new Exception(StringResources.Language.NotSupportedDataType);
				IL_284:
				bool flag4 = address[1] == 'N' || address[1] == 'n';
				if (flag4)
				{
					operateResult.Content1 = MelsecMcDataType.CN;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CN.FromBase);
					goto IL_38A;
				}
				bool flag5 = address[1] == 'S' || address[1] == 's';
				if (flag5)
				{
					operateResult.Content1 = MelsecMcDataType.CS;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CS.FromBase);
					goto IL_38A;
				}
				bool flag6 = address[1] == 'C' || address[1] == 'c';
				if (flag6)
				{
					operateResult.Content1 = MelsecMcDataType.CC;
					operateResult.Content2 = Convert.ToUInt16(address.Substring(2), MelsecMcDataType.CC.FromBase);
					goto IL_38A;
				}
				throw new Exception(StringResources.Language.NotSupportedDataType);
				IL_37A:
				throw new Exception(StringResources.Language.NotSupportedDataType);
				IL_38A:;
			}
			catch (Exception ex)
			{
				operateResult.Message = ex.Message;
				return operateResult;
			}
			operateResult.IsSuccess = true;
			return operateResult;
		}

		/// <summary>
		/// 返回读取的地址及长度信息
		/// </summary>
		/// <param name="address">读取的地址信息</param>
		/// <param name="isNewVersion">是否是新版的串口访问类</param>
		/// <returns>带起始地址的结果对象</returns>
		// Token: 0x060008C3 RID: 2243 RVA: 0x00030C5C File Offset: 0x0002EE5C
		private static OperateResult<ushort> FxCalculateWordStartAddress(string address, bool isNewVersion)
		{
			OperateResult<MelsecMcDataType, ushort> operateResult = MelsecFxSerialOverTcp.FxAnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<ushort> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<ushort>(operateResult);
			}
			else
			{
				ushort num = operateResult.Content2;
				bool flag2 = operateResult.Content1 == MelsecMcDataType.D;
				if (flag2)
				{
					bool flag3 = num >= 8000;
					if (flag3)
					{
						num = (num - 8000) * 2 + 3584;
					}
					else
					{
						num = (isNewVersion ? (num * 2 + 16384) : (num * 2 + 4096));
					}
				}
				else
				{
					bool flag4 = operateResult.Content1 == MelsecMcDataType.CN;
					if (flag4)
					{
						bool flag5 = num >= 200;
						if (flag5)
						{
							num = (num - 200) * 4 + 3072;
						}
						else
						{
							num = num * 2 + 2560;
						}
					}
					else
					{
						bool flag6 = operateResult.Content1 == MelsecMcDataType.TN;
						if (!flag6)
						{
							return new OperateResult<ushort>(StringResources.Language.MelsecCurrentTypeNotSupportedWordOperate);
						}
						num = num * 2 + 2048;
					}
				}
				result = OperateResult.CreateSuccessResult<ushort>(num);
			}
			return result;
		}

		/// <summary>
		/// 返回读取的地址及长度信息，以及当前的偏置信息
		/// </summary><param name="address">读取的地址信息</param>
		/// <returns>带起始地址的结果对象</returns>
		// Token: 0x060008C4 RID: 2244 RVA: 0x00030D68 File Offset: 0x0002EF68
		private static OperateResult<ushort, ushort, ushort> FxCalculateBoolStartAddress(string address)
		{
			OperateResult<MelsecMcDataType, ushort> operateResult = MelsecFxSerialOverTcp.FxAnalysisAddress(address);
			bool flag = !operateResult.IsSuccess;
			OperateResult<ushort, ushort, ushort> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<ushort, ushort, ushort>(operateResult);
			}
			else
			{
				ushort num = operateResult.Content2;
				bool flag2 = operateResult.Content1 == MelsecMcDataType.M;
				if (flag2)
				{
					bool flag3 = num >= 8000;
					if (flag3)
					{
						num = (num - 8000) / 8 + 480;
					}
					else
					{
						num = num / 8 + 256;
					}
				}
				else
				{
					bool flag4 = operateResult.Content1 == MelsecMcDataType.X;
					if (flag4)
					{
						num = num / 8 + 128;
					}
					else
					{
						bool flag5 = operateResult.Content1 == MelsecMcDataType.Y;
						if (flag5)
						{
							num = num / 8 + 160;
						}
						else
						{
							bool flag6 = operateResult.Content1 == MelsecMcDataType.S;
							if (flag6)
							{
								num /= 8;
							}
							else
							{
								bool flag7 = operateResult.Content1 == MelsecMcDataType.CS;
								if (flag7)
								{
									num = num / 8 + 448;
								}
								else
								{
									bool flag8 = operateResult.Content1 == MelsecMcDataType.CC;
									if (flag8)
									{
										num = num / 8 + 960;
									}
									else
									{
										bool flag9 = operateResult.Content1 == MelsecMcDataType.TS;
										if (flag9)
										{
											num = num / 8 + 192;
										}
										else
										{
											bool flag10 = operateResult.Content1 == MelsecMcDataType.TC;
											if (!flag10)
											{
												return new OperateResult<ushort, ushort, ushort>(StringResources.Language.MelsecCurrentTypeNotSupportedBitOperate);
											}
											num = num / 8 + 704;
										}
									}
								}
							}
						}
					}
				}
				result = OperateResult.CreateSuccessResult<ushort, ushort, ushort>(num, operateResult.Content2, operateResult.Content2 % 8);
			}
			return result;
		}
	}
}
